/*
 * Copyright (c) 2024 Huawei Technologies Co., Ltd.
 * openFuyao is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

package main

import (
	"context"
	"fmt"
	"os"
	"regexp"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	klog "k8s.io/klog/v2"

	v1 "openfuyao.com/colocation-service/pkg/apis/colocation/v1"
	"openfuyao.com/colocation-service/pkg/client/clientset/versioned"
)

func main() {
	klog.InitFlags(nil)

	restClientConfig, _ := clientcmd.BuildConfigFromFlags("", "./admin.conf")

	client, _ := versioned.NewForConfig(restClientConfig)
	clientset, _ := kubernetes.NewForConfig(restClientConfig)

	rule := v1.ColocationWorkloadMatchRule{}
	rule.TypeMeta.APIVersion = "v1"
	rule.TypeMeta.Kind = "ColocationWorkloadMatchRule"
	rule.ObjectMeta.Namespace = os.Getenv("POD_NAMESPACE")
	rule.ObjectMeta.Name = "ab-ce.ef_okabc"
	rule.Spec.Selectors = []v1.Selector{
		{
			Namespace:     os.Getenv("POD_NAMESPACE"),
			Name:          "nginx",
			WorkloadTypes: []string{"Deployment"},
			Selector: &metav1.LabelSelector{
				MatchLabels: map[string]string{
					"app": "nginx",
				},
			},
		},
	}

	// 校验：RuleName字符串格式化校验
	isValid := StringValidityCheck(rule.ObjectMeta.Name, NormalMode)
	klog.Info(rule.ObjectMeta.Name, isValid)
	if !isValid {
		fmt.Println("rule name must consist of alphanumeric characters, '-', '_' or '.'," +
			"and must start and end with an alphanumeric character")
		return
	}

	savedRule, err := client.ColocationV1().ColocationWorkloadMatchRules(
		rule.ObjectMeta.Namespace).Create(context.TODO(), &rule, metav1.CreateOptions{})
	klog.Info(savedRule.ObjectMeta.Name, err)

	rules, _ := client.ColocationV1().ColocationWorkloadMatchRules("").List(context.TODO(), metav1.ListOptions{})
	for _, rule := range rules.Items {
		fmt.Println("rule.name:", rule.ObjectMeta.Name)
		selectors := rule.Spec.Selectors
		for _, selector := range selectors {
			fmt.Println("  rule.namespace:", selector.Namespace)
			labelSelector, err := metav1.LabelSelectorAsSelector(selector.Selector)
			if err != nil {
				fmt.Errorf("  couldn't convert rule selector: %v", err)
			}
			fmt.Println("  rule.labelSelector:", labelSelector.String())
			pods, err := clientset.CoreV1().Pods(selector.Namespace).List(context.TODO(),
				metav1.ListOptions{LabelSelector: labelSelector.String()})
			if err != nil {
				fmt.Errorf("  couldn't convert rule selector: %v", err)
			}

			for _, pod := range pods.Items {
				fmt.Println("  rule.match.workload:", pod.Name)
			}
		}
	}
}

type StringCheckMode string

const (
	// 常规模式
	NormalMode StringCheckMode = "normal"
	// 自定义模式: 标签Key的格式化校验
	LabelKeyMode StringCheckMode = "label_key_mode"
)

func StringValidityCheck(input string, mode StringCheckMode) bool {
	if input == "" {
		return false
	}

	var pattern string
	if mode == NormalMode {
		pattern = "^([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$"
	} else if mode == LabelKeyMode {
		pattern = "[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*"
	}
	re := regexp.MustCompile(pattern)

	isValid := re.MatchString(input)
	if isValid {
		return true
	} else {
		return false
	}
}
